import { HttpClient, HttpResponse } from '@angular/common/http';

export class APIBase<W_Model = any, R_Model = any> {
  constructor(private client: HttpClient, protected baseURL: string) {

    window['$angularHttp']=this;

  }
  call(methodName:string,args:string,baseURL?:string){
    let oldBaseURL=this.baseURL
    this.baseURL=baseURL||oldBaseURL
    let res=this[methodName].apply(this,args)


    this.baseURL=oldBaseURL
    return res;
  }

  create(t: W_Model) {
    return this.client.post(this.baseURL, t).toPromise();
  }
  update(t: W_Model) {
    return this.client.put(this.baseURL, t).toPromise();
  }

  delete(ids) {
    return this.client.request<void>('DELETE', this.baseURL, { body: ids }).toPromise();
  }

  async list(listOption?: ListOption | any) {
    if (listOption) {
      Object.keys(listOption)
        .filter(key => listOption[key] === null || listOption[key] === '')
        .forEach(key => delete listOption[key]);
    }
    const resp = await this.client
      .get<R_Model[]>(this.baseURL, { observe: 'response', params: listOption as any })
      .toPromise();
    const result = toListResult(resp);
    if (!result.list) {
      result.list = [];
    }
    // 查找ID
    result.list.forEach((v: any) => {
      if (v.id !== 0 && !v.id) {
        const primary_key = Object.keys(v).find(key => key.includes('_id'));
        v.id = v[primary_key];
      }
    });
    return result;
  }

  get<D = R_Model>(id: number) {
    const url = this.baseURL + '/' + id;
    return this.client.get<R_Model>(url).toPromise();
  }

  getWithAreaId<D = R_Model>(id: number, areaId: number) {
    const url = this.baseURL + '/' + id + `?area_id=${areaId}`;
    return this.client.get<R_Model>(url).toPromise();
  }

  patch<K extends keyof R_Model>(key: K, value: R_Model[K], id: number) {
    console.log('arguments in patch---:',arguments)
    const body = { [key]: value, id };
    const url = this.baseURL + '/' + key;
    return this.client.patch<void>(url, body).toPromise();
  }

  batch<K extends keyof R_Model>(key: K, value: R_Model[K], ids: number[], all = false) {
    console.log('arguments in batch---:',arguments)
    const body = { [key]: value, ids, all };
    const url = this.baseURL + '/' + key;
    return this.client.patch<void>(url, body).toPromise();
  }
}
export interface ListOption {
  page?: number; // default 1
  count?: number;
  order_by?: string;
  order?: string;
  keyword?: string;
  filter_ids?:string
}
export interface ListResult<T = any> {
  total: number;
  page: number;
  pageSize: number;
  list: Array<T>;
}
function toListResult<T>(resp: HttpResponse<T[]>): ListResult<T> {
  return {
    total: Number(resp.headers.get('total_row_count')),
    page: Number(resp.headers.get('page')),
    pageSize: Number(resp.headers.get('row_count_perpage')),
    list: resp.body,
  };
}

export class ArrayAPIBase<T> extends APIBase<T, T> {
  constructor(private arr: Array<T>, private pageSize = 10) {
    super(null, null);
  }
  search: (t: T, keyword: string) => boolean;
  async list(opt?: ListOption) {
    var list = this.arr;
    const page = opt ? opt.page || 1 : 1;
    if (opt.keyword && this.search) {
      list = list.filter(t => this.search(t, opt.keyword));
    }
    return <ListResult<T>>{
      total: list.length,
      page: page,
      pageSize: this.pageSize,
      list: list.slice((page - 1) * this.pageSize, page * this.pageSize),
    };
  }
}

